package store

import (
	"errors"
	"fmt"
	"go-stage/core"
	"go-stage/micro/system/cache"
	"go-stage/micro/system/model"
	"time"
)

type dictStoreImpl interface {
	FindByUUID(uuid string) (*model.DictModel, error)
	FindChildrenByUUID(uuid string) ([]model.DictModel, error)
	FindGroupByUUID(uuid string) ([]model.DictModel, error)
	Insert(dict *model.DictModel) (*model.DictModel, error)
	Update(dict *model.DictModel) (*model.DictModel, error)
	Remove(uuid string) (*model.DictModel, error)
	FindRootByUUID(uuid string) (*model.DictModel, error)
}

type dictStore struct{}

var DictStore dictStoreImpl = (*dictStore)(nil)

// FindByUUID 依据UUID获取字典数据
func (dictStore *dictStore) FindByUUID(uuid string) (*model.DictModel, error) {
	if uuid == "" {
		return nil, errors.New("param uuid is empty")
	}
	dictModel, err := cache.DictCache.Get(uuid)
	if err != nil {
		core.Log.Errorf("cache dictcache get error: %v", err)
	} else if dictModel != nil {
		return dictModel, nil
	}

	var dictModels []model.DictModel
	if err := core.DB.Select(&dictModels, "select id, uuid, `describe`, context, value, parent_uuid, group_uuid, create_time, update_time, status from dict_info where uuid = ? and status = 1", uuid); err != nil {
		return nil, err
	}
	if len(dictModels) > 0 {
		if err := cache.DictCache.Set(&dictModels[0]); err != nil {
			core.Log.Errorf("cache dictcache ")
		}
		return &dictModels[0], nil
	}
	return nil, nil
}

// FindChildrenByUUID 依据UUID获取其子级字典数据
func (dictStore *dictStore) FindChildrenByUUID(uuid string) ([]model.DictModel, error) {
	var dictModels []model.DictModel
	if err := core.DB.Select(&dictModels, "select id, uuid, `describe`, context, value, parent_uuid, group_uuid, create_time, update_time, status from dict_info where parent_uuid = ? and status = 1", uuid); err != nil {
		return nil, err
	}
	return dictModels, nil
}

// FindGroupByUUID 依据UUID获取当前UUID组所有数据
func (dictStore *dictStore) FindGroupByUUID(uuid string) ([]model.DictModel, error) {
	var dictModels []model.DictModel
	if err := core.DB.Select(&dictModels, "select id, uuid, `describe`, context, value, parent_uuid, group_uuid, create_time, update_time, status from dict_info where group_uuid = ? and status = 1", uuid); err != nil {
		return nil, err
	}
	return dictModels, nil
}

// Insert 添加字典
func (dictStore *dictStore) Insert(dict *model.DictModel) (*model.DictModel, error) {
	dict.Uuid = core.UUIDReplace("-", "")
	dict.CreateTime = time.Now().Unix()
	dict.UpdateTime = dict.CreateTime
	if dict.ParentUuid != "" {
		root, err := dictStore.FindRootByUUID(dict.ParentUuid)
		if err != nil {
			return nil, err
		}
		dict.GroupUuid = root.Uuid
	}
	res, err := core.DB.Exec("insert into dict_info (uuid, `describe`, context, value, parent_uuid, group_uuid, create_time, update_time, status) VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?)",
		dict.Uuid,
		dict.Describe,
		dict.Context,
		dict.Value,
		dict.ParentUuid,
		dict.GroupUuid,
		dict.CreateTime,
		dict.UpdateTime,
		dict.Status,
	)
	if err != nil {
		return nil, err
	}
	dict.Id, _ = res.LastInsertId()
	return dict, nil
}

// Update 修改字典
func (dictStore *dictStore) Update(dict *model.DictModel) (*model.DictModel, error) {
	sql := "update dict_info %s where uuid = ?"

	params := make(map[string]interface{})
	if dict.Describe != "" {
		params["describe"] = dict.Describe
	}
	if dict.Context != "" {
		params["context"] = dict.Context
	}
	if dict.Value != "" {
		params["value"] = dict.Value
	}
	if dict.ParentUuid != "" {
		params["parent_uuid"] = dict.ParentUuid
	}
	if dict.GroupUuid != "" {
		params["group_uuid"] = dict.GroupUuid
	}
	if dict.Status != 0 {
		params["status"] = dict.Status
	}
	params["update_time"] = time.Now().Unix()

	set, param := core.GeneratorSqlSet(params)
	param = append(param, dict.Uuid)
	_, err := core.DB.Exec(fmt.Sprintf(sql, set), param...)
	if err != nil {
		return nil, err
	}
	cache.DictCache.Del(dict.Uuid)
	return dict, nil
}

// Remove 依据UUID删除(假删)字典信息
func (dictStore *dictStore) Remove(uuid string) (*model.DictModel, error) {
	result, err := dictStore.FindByUUID(uuid)
	if err != nil {
		return nil, err
	}
	if result == nil {
		return nil, errors.New("this dict uuid is empty")
	}

	_, err = core.DB.Exec("update dict_info set status = 3 where uuid = ?", uuid)
	if err != nil {
		return nil, err
	}
	cache.DictCache.Del(uuid)
	return result, nil
}

// FindRootByUUID 依据UUID获取当前字典的根节点字典信息
func (dictStore *dictStore) FindRootByUUID(uuid string) (*model.DictModel, error) {
	dictModel, err := dictStore.FindByUUID(uuid)
	if err != nil {
		return nil, err
	}
	for dictModel.ParentUuid != "" && dictModel.ParentUuid != dictModel.Uuid {
		dictModel, err = dictStore.FindByUUID(dictModel.ParentUuid)
		if err != nil {
			return nil, err
		}
	}
	return dictModel, nil
}
